//
// Created by yanhai on 2021/11/3.
//

#include <iostream>
#include <thread>
#include <cstring>

#include "utility/hashtable/flow_hashtable.h"

#include "packet.h"
#include "flow.h"

void worker_thread2(std::shared_ptr<FlowHashTable<Flow, Packet>> flow_table)
{
    unsigned int delay = 100;

    srand(time(NULL));

    while (delay--) {
        time_t t = time(NULL);
        unsigned int port = rand() % 10;
        Packet *p1 = PacketAlloc(1, 2, 3, port, t);
        Flow *f1 = flow_table->FindAndNew(p1);
        assert(f1 != NULL);
        f1->count++;
        std::cout << "flow count: " << f1->count << std::endl;
//        std::this_thread::sleep_for(std::chrono::seconds(1));
        f1->mutex.unlock();
        PacketFree(p1);
        std::this_thread::sleep_for(std::chrono::milliseconds (100));
    }
}

void flow_manager2(std::shared_ptr<FlowHashTable<Flow, Packet>> flow_table)
{
    while (true) {
        std::cout << "flow foreach start----------------" << std::endl;
        flow_table->Foreach([](Flow *f) -> bool {
            std::cout << f->src_addr << ":" << f->src_port << " -> "
                      << f->dst_addr << ":" << f->dst_port
                      << ", count=" << f->count << std::endl;
            return true;
        });
        std::cout << "flow foreach end----------------" << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

int main()
{
    auto flow_table = std::make_shared<FlowHashTable<Flow, Packet>>(1024, FlowGetNew, FlowInit);

    std::thread t1(worker_thread2, flow_table);
    std::thread t2(flow_manager2, flow_table);

    t2.detach();
    t1.join();

    return 0;
}